/**
 * TransNode.h
 * Coyright (c) 2009 Xiaofeng Gu. All Rights Reserved.
 * Author : Xiaofeng Gu
 *
 * Creation Data : 2009/06/11
 */

#pragma once

#include "Bone.h"
#include "Vec.h"
#include "Difference.h"
#include <vector>

#include "SKObject.h"
#include "ISelect.h"

class CTransNode;
class CKnot;
typedef std::vector<CTransNode*>		Nodes;

class CTransNode : public CSKObject, public ISelect
{
public:
	CTransNode(CKnot* pParentKnot);
	virtual ~CTransNode();

	virtual bool				OnRead(CXMLParser* pParser);
	virtual bool				OnWrite(CXMLParser* pParser);

	virtual bool				OnSelect(double Ray[6]);

// operator
	NodeDifference*	operator-(CTransNode& node);
	void			operator++();
	void			operator--();

// method
	virtual void				Render();
	virtual CGBox&				GetRangeBox();

public:
	// method
	bool						RotateTo(CVec& ToVec);
	bool						Rotate(CVec& Ref, double dAngle);
	bool						Rotate(CJoint& oJoint, CVec& Ref, double dAngle);
	bool						Screw(double dAngle);
	bool						Move(CVec& Ref);
	bool						MoveTo(CVec& Pt);
	bool						Zoom(double k);

	CTransNode*					Copy(CKnot* pParentKnot);

	virtual void				Back();
	virtual void				Rollback();


// property
	CBone*						GetBone() { return &m_oBone; }
	void						AddChild(CTransNode* pChild) { m_oChildren.push_back(pChild); }
	Nodes*						GetChildren() { return &m_oChildren; }
	void						SetParent(CTransNode* pParent) { m_pParent = pParent; }
	CTransNode*					GetParent() { return m_pParent; }
	virtual CString				GetName() { return _T("Node"); }
	virtual SKObjectType		GetSKObjectType() { return eNode; }
	CKnot*					GetParentKnot() { return m_pParentKnot; }
	CVec&						GetLastMovement() { return m_lastMovement; }

private:
	CBone				m_oBackBone;
	Nodes				m_oChildren;
	CTransNode*			m_pParent;
	CKnot*			m_pParentKnot;

private:
	NodeDifference		m_oDiff;
	CVec*				m_pRotAxis;
	double*				m_pAngle;
	double*				m_pScrewAngle;
	double*				m_pFactor;

	CVec				m_lastMovement;

// the attributes to be read and writed
private:
	CBone				m_oBone;
	CString				m_strNodeName;
};